use rustcloud_core::{Request, Response, ServiceInstance, ServiceRegistry, LoadBalancerStrategy};
use rustcloud_registry::InMemoryRegistry;
use rustcloud_loadbalancer::LoadBalancerManager;
use rustcloud_transport::HttpTransport;
use rustcloud_circuit_breaker::{DefaultCircuitBreaker, CircuitBreakerConfig};
use rustcloud_proxy::{AdvancedClientProxy, AdvancedProxyBuilder, LoggingInterceptor, TracingInterceptor, AuthenticationInterceptor, CacheConfig, CacheStrategy};
use std::sync::Arc;
use std::time::Duration;
use wiremock::{MockServer, Mock, ResponseTemplate};
use wiremock::matchers::{method, path, header};

/// 测试高级代理的完整端到端流程
#[tokio::test]
async fn test_advanced_proxy_end_to_end() {
    // 1. 启动模拟服务器
    let server = MockServer::start().await;
    let mock_response_body = "Advanced Proxy Response";
    Mock::given(method("POST"))
        .and(path("/api/advanced-test"))
        .respond_with(ResponseTemplate::new(200).set_body_string(mock_response_body))
        .mount(&server)
        .await;

    // 2. 设置服务注册中心
    let registry = Arc::new(InMemoryRegistry::new());
    let server_uri = server.uri();
    let parts: Vec<&str> = server_uri.split(':').collect();
    let host = parts[1].trim_start_matches("//");
    let port = parts[2].parse::<u16>().unwrap();

    let instance = ServiceInstance::new("advanced-service", host, port, "http");
    registry.register(instance).await.unwrap();

    // 3. 使用构建器创建高级代理
    let load_balancer = Arc::new(LoadBalancerManager::new(LoadBalancerStrategy::RoundRobin));
    let transport = Arc::new(HttpTransport::new());
    let circuit_breaker = Arc::new(DefaultCircuitBreaker::new(CircuitBreakerConfig::default()));

    let proxy = AdvancedProxyBuilder::new("advanced-service".to_string())
        .registry(registry)
        .load_balancer(load_balancer)
        .transport(transport)
        .circuit_breaker(circuit_breaker)
        .build()
        .await
        .unwrap();

    // 4. 配置缓存
    let cache_config = CacheConfig {
        enabled: true,
        strategy: CacheStrategy::TimeBasedCache { ttl: Duration::from_secs(300) },
        compress: false,
        serialize_format: "json".to_string(),
    };
    let proxy = proxy.with_cache_config(cache_config);

    // 5. 添加自定义拦截器
    let logging_interceptor = Arc::new(LoggingInterceptor::new());
    let tracing_interceptor = Arc::new(TracingInterceptor::new("advanced-service".to_string()));
    let auth_interceptor = Arc::new(AuthenticationInterceptor::bearer_token("test-token".to_string()));

    proxy.add_request_interceptor(auth_interceptor).await;
    proxy.add_request_interceptor(tracing_interceptor).await;
    proxy.add_request_interceptor(logging_interceptor.clone()).await;
    proxy.add_response_interceptor(logging_interceptor).await;

    // 6. 发送请求
    let mut request = Request::new("advanced-service", "POST", "/api/advanced-test");
    request.set_body(b"test request body".to_vec());

    let response = proxy.call_with_retry(request).await.unwrap();

    // 7. 验证结果
    assert_eq!(response.status, 200);
    let body = String::from_utf8(response.body.unwrap()).unwrap();
    assert_eq!(body, mock_response_body);

    // 8. 验证统计信息
    let call_stats = proxy.get_call_stats().await;
    assert_eq!(call_stats.total_calls, 1);
    assert_eq!(call_stats.successful_calls, 1);
    assert_eq!(call_stats.failed_calls, 0);

    let service_stats = proxy.get_service_stats("advanced-service").await;
    assert!(service_stats.is_some());
    let stats = service_stats.unwrap();
    assert_eq!(stats.total_requests, 1);
    assert_eq!(stats.successful_requests, 1);
    assert_eq!(stats.failed_requests, 0);
}

/// 测试认证拦截器功能
#[tokio::test]
async fn test_authentication_interceptor() {
    // 启动模拟服务器，验证认证头
    let server = MockServer::start().await;
    Mock::given(method("GET"))
        .and(path("/api/auth-test"))
        .and(header("Authorization", "Bearer secret-token"))
        .respond_with(ResponseTemplate::new(200).set_body_string("Authenticated"))
        .mount(&server)
        .await;

    // 设置代理
    let registry = Arc::new(InMemoryRegistry::new());
    let server_uri = server.uri();
    let parts: Vec<&str> = server_uri.split(':').collect();
    let host = parts[1].trim_start_matches("//");
    let port = parts[2].parse::<u16>().unwrap();

    let instance = ServiceInstance::new("auth-service", host, port, "http");
    registry.register(instance).await.unwrap();

    let load_balancer = Arc::new(LoadBalancerManager::new(LoadBalancerStrategy::RoundRobin));
    let transport = Arc::new(HttpTransport::new());
    let circuit_breaker = Arc::new(DefaultCircuitBreaker::new(CircuitBreakerConfig::default()));

    let proxy = AdvancedProxyBuilder::new("auth-service".to_string())
        .registry(registry)
        .load_balancer(load_balancer)
        .transport(transport)
        .circuit_breaker(circuit_breaker)
        .build()
        .await
        .unwrap();

    // 添加认证拦截器
    let auth_interceptor = Arc::new(AuthenticationInterceptor::bearer_token("secret-token".to_string()));
    proxy.add_request_interceptor(auth_interceptor).await;

    // 发送请求
    let request = Request::new("auth-service", "GET", "/api/auth-test");
    let response = proxy.call_with_retry(request).await.unwrap();

    assert_eq!(response.status, 200);
    let body = String::from_utf8(response.body.unwrap()).unwrap();
    assert_eq!(body, "Authenticated");
}

/// 测试API Key认证
#[tokio::test]
async fn test_api_key_authentication() {
    let server = MockServer::start().await;
    Mock::given(method("GET"))
        .and(path("/api/key-test"))
        .and(header("X-API-Key", "my-api-key"))
        .respond_with(ResponseTemplate::new(200).set_body_string("API Key Valid"))
        .mount(&server)
        .await;

    let registry = Arc::new(InMemoryRegistry::new());
    let server_uri = server.uri();
    let parts: Vec<&str> = server_uri.split(':').collect();
    let host = parts[1].trim_start_matches("//");
    let port = parts[2].parse::<u16>().unwrap();

    let instance = ServiceInstance::new("key-service", host, port, "http");
    registry.register(instance).await.unwrap();

    let load_balancer = Arc::new(LoadBalancerManager::new(LoadBalancerStrategy::RoundRobin));
    let transport = Arc::new(HttpTransport::new());
    let circuit_breaker = Arc::new(DefaultCircuitBreaker::new(CircuitBreakerConfig::default()));

    let proxy = AdvancedProxyBuilder::new("key-service".to_string())
        .registry(registry)
        .load_balancer(load_balancer)
        .transport(transport)
        .circuit_breaker(circuit_breaker)
        .build()
        .await
        .unwrap();

    // 添加API Key认证拦截器
    let auth_interceptor = Arc::new(AuthenticationInterceptor::api_key("my-api-key".to_string()));
    proxy.add_request_interceptor(auth_interceptor).await;

    // 发送请求
    let request = Request::new("key-service", "GET", "/api/key-test");
    let response = proxy.call_with_retry(request).await.unwrap();

    assert_eq!(response.status, 200);
    let body = String::from_utf8(response.body.unwrap()).unwrap();
    assert_eq!(body, "API Key Valid");
}

/// 测试缓存功能的实际效果
#[tokio::test]
async fn test_response_caching_integration() {
    let server = MockServer::start().await;
    
    // 设置一个计数器来跟踪实际的服务器调用
    let call_counter = Arc::new(std::sync::atomic::AtomicUsize::new(0));
    let counter_clone = call_counter.clone();
    
    Mock::given(method("GET"))
        .and(path("/api/cache-test"))
        .respond_with(move |_req| {
            let count = counter_clone.fetch_add(1, std::sync::atomic::Ordering::SeqCst) + 1;
            ResponseTemplate::new(200).set_body_string(format!("Response #{}", count))
        })
        .mount(&server)
        .await;

    let registry = Arc::new(InMemoryRegistry::new());
    let server_uri = server.uri();
    let parts: Vec<&str> = server_uri.split(':').collect();
    let host = parts[1].trim_start_matches("//");
    let port = parts[2].parse::<u16>().unwrap();

    let instance = ServiceInstance::new("cache-service", host, port, "http");
    registry.register(instance).await.unwrap();

    let load_balancer = Arc::new(LoadBalancerManager::new(LoadBalancerStrategy::RoundRobin));
    let transport = Arc::new(HttpTransport::new());
    let circuit_breaker = Arc::new(DefaultCircuitBreaker::new(CircuitBreakerConfig::default()));

    let proxy = AdvancedProxyBuilder::new("cache-service".to_string())
        .registry(registry)
        .load_balancer(load_balancer)
        .transport(transport)
        .circuit_breaker(circuit_breaker)
        .build()
        .await
        .unwrap();

    // 启用缓存
    let cache_config = CacheConfig {
        enabled: true,
        strategy: CacheStrategy::TimeBasedCache { ttl: Duration::from_secs(60) },
        compress: false,
        serialize_format: "json".to_string(),
    };
    let proxy = proxy.with_cache_config(cache_config);

    // 第一次请求
    let request1 = Request::new("cache-service", "GET", "/api/cache-test");
    let response1 = proxy.call_with_retry(request1).await.unwrap();
    assert_eq!(response1.status, 200);
    let body1 = String::from_utf8(response1.body.unwrap()).unwrap();
    assert_eq!(body1, "Response #1");

    // 第二次相同请求应该使用缓存
    let request2 = Request::new("cache-service", "GET", "/api/cache-test");
    let response2 = proxy.call_with_retry(request2).await.unwrap();
    assert_eq!(response2.status, 200);
    let body2 = String::from_utf8(response2.body.unwrap()).unwrap();
    assert_eq!(body2, "Response #1"); // 应该是缓存的第一个响应

    // 验证服务器只被调用了一次
    assert_eq!(call_counter.load(std::sync::atomic::Ordering::SeqCst), 1);

    // 验证缓存统计
    let (total_entries, expired_entries) = proxy.get_cache_stats().await;
    assert!(total_entries > 0);
    assert_eq!(expired_entries, 0);
}

/// 测试重试机制的实际效果
#[tokio::test]
async fn test_retry_mechanism_integration() {
    let server = MockServer::start().await;
    
    let call_counter = Arc::new(std::sync::atomic::AtomicUsize::new(0));
    let counter_clone = call_counter.clone();
    
    // 前两次调用返回500错误，第三次成功
    Mock::given(method("GET"))
        .and(path("/api/retry-test"))
        .respond_with(move |_req| {
            let count = counter_clone.fetch_add(1, std::sync::atomic::Ordering::SeqCst) + 1;
            if count <= 2 {
                ResponseTemplate::new(500).set_body_string("Server Error")
            } else {
                ResponseTemplate::new(200).set_body_string("Success on retry")
            }
        })
        .mount(&server)
        .await;

    let registry = Arc::new(InMemoryRegistry::new());
    let server_uri = server.uri();
    let parts: Vec<&str> = server_uri.split(':').collect();
    let host = parts[1].trim_start_matches("//");
    let port = parts[2].parse::<u16>().unwrap();

    let instance = ServiceInstance::new("retry-service", host, port, "http");
    registry.register(instance).await.unwrap();

    let load_balancer = Arc::new(LoadBalancerManager::new(LoadBalancerStrategy::RoundRobin));
    let transport = Arc::new(HttpTransport::new());
    let circuit_breaker = Arc::new(DefaultCircuitBreaker::new(CircuitBreakerConfig::default()));

    let proxy = AdvancedProxyBuilder::new("retry-service".to_string())
        .registry(registry)
        .load_balancer(load_balancer)
        .transport(transport)
        .circuit_breaker(circuit_breaker)
        .build()
        .await
        .unwrap();

    // 发送请求，应该在第三次重试时成功
    let request = Request::new("retry-service", "GET", "/api/retry-test");
    let response = proxy.call_with_retry(request).await.unwrap();

    assert_eq!(response.status, 200);
    let body = String::from_utf8(response.body.unwrap()).unwrap();
    assert_eq!(body, "Success on retry");

    // 验证服务器被调用了3次
    assert_eq!(call_counter.load(std::sync::atomic::Ordering::SeqCst), 3);

    // 验证统计信息
    let call_stats = proxy.get_call_stats().await;
    assert_eq!(call_stats.total_calls, 1); // 从代理角度看只有一次调用
    assert_eq!(call_stats.successful_calls, 1);
    assert_eq!(call_stats.failed_calls, 0);
}

/// 测试批量调用功能
#[tokio::test]
async fn test_batch_calls_integration() {
    let server = MockServer::start().await;
    
    // 为不同路径设置不同响应
    for i in 1..=3 {
        Mock::given(method("GET"))
            .and(path(format!("/api/batch-{}", i)))
            .respond_with(ResponseTemplate::new(200).set_body_string(format!("Batch Response {}", i)))
            .mount(&server)
            .await;
    }

    let registry = Arc::new(InMemoryRegistry::new());
    let server_uri = server.uri();
    let parts: Vec<&str> = server_uri.split(':').collect();
    let host = parts[1].trim_start_matches("//");
    let port = parts[2].parse::<u16>().unwrap();

    let instance = ServiceInstance::new("batch-service", host, port, "http");
    registry.register(instance).await.unwrap();

    let load_balancer = Arc::new(LoadBalancerManager::new(LoadBalancerStrategy::RoundRobin));
    let transport = Arc::new(HttpTransport::new());
    let circuit_breaker = Arc::new(DefaultCircuitBreaker::new(CircuitBreakerConfig::default()));

    let proxy = AdvancedProxyBuilder::new("batch-service".to_string())
        .registry(registry)
        .load_balancer(load_balancer)
        .transport(transport)
        .circuit_breaker(circuit_breaker)
        .build()
        .await
        .unwrap();

    // 准备批量请求
    let requests = vec![
        Request::new("batch-service", "GET", "/api/batch-1"),
        Request::new("batch-service", "GET", "/api/batch-2"),
        Request::new("batch-service", "GET", "/api/batch-3"),
    ];

    // 执行批量调用
    let results = proxy.batch_call(requests).await;

    // 验证结果
    assert_eq!(results.len(), 3);
    for (i, result) in results.iter().enumerate() {
        assert!(result.is_ok());
        let response = result.as_ref().unwrap();
        assert_eq!(response.status, 200);
        let body = String::from_utf8(response.body.clone().unwrap()).unwrap();
        assert_eq!(body, format!("Batch Response {}", i + 1));
    }

    // 验证统计信息
    let call_stats = proxy.get_call_stats().await;
    assert_eq!(call_stats.total_calls, 3);
    assert_eq!(call_stats.successful_calls, 3);
    assert_eq!(call_stats.failed_calls, 0);
}